﻿using UnityEngine;

namespace Core
{
    public class InventoryComponent : Entity, IAwake
    {
        private Unit unit;
        public ItemContainer backpack { get; private set; }
        public ItemContainer equipment { get; private set; }
        public ItemSlot CurSlot { get; private set; }
        void IAwake.Awake()
        {
            unit = GetParent<Unit>();
            var itemContainerMgr = unit.GetComponent<ItemContainerMgr>();
            backpack = itemContainerMgr.Create($"inventory:{unit.InstanceId}", 25);
            equipment = itemContainerMgr.Create($"equipment:{unit.InstanceId}", 10);
        }

        public void ChangeCurrentItemSlot(ItemSlot slot)
        {
            var oldSlot = CurSlot;
            CurSlot = slot;
            World.GetComponent<EventComponent>().Publish(new CurrentItemSlostChange{unit = unit, oldSlot = oldSlot, newSlot = slot });
        }

        public int GetCount(int itemId)
        {
            return backpack.GetItemCount(itemId);   
        }

        public bool CanAddItem(int itemId, int count)
        {
            return backpack.CanAddItemCount(itemId) >= count;
        }

        public bool TryAddItem(int itemId, int count)
        {
            var config = World.GetComponent<ConfigComponent>().GetConfig<ItemConfig>(itemId);
            if (config == null)
                return false;

            if (!CanAddItem(itemId, count))
                return false;

            backpack.AddItem(itemId, count);

            return true;
        }

        public bool RemoveItem(int itemId, int count)
        {
            var config = World.GetComponent<ConfigComponent>().GetConfig<ItemConfig>(itemId);
            if (config == null)
                return false;

            var total = backpack.GetItemCount(itemId);
            if (total < count)
                return false;

            return backpack.RemoveItem(itemId, count);
        }

        public void Swap(ItemSlot slotA, ItemSlot slotB, int swapCount = 0)
        {
            if (slotA == slotB)
                return;

            if(swapCount > 0 && swapCount < slotA.count && slotB.IsEmpty)
            {
                slotA.UpdateCount(-swapCount);
                slotB.UpdateItem(slotA.itemId, swapCount);
            }
            else
            {
                var itemId = slotA.itemId;
                var count = slotA.count;
                slotA.UpdateItem(slotB.itemId, slotB.count);
                slotB.UpdateItem(itemId, count);
            }
        }

        public void DropItem(int itemId, int count, Vector3 position)
        {
            if (!World.GetComponent<NavMeshComponent>().IsValid(position))
                return;

            if(RemoveItem(itemId, count))
            {
                World.GetComponent<SceneItemMgr>().CreateItem(itemId, count, position);
            }
        }
    }
}
